package IC;

/*
 * All Rights Reserved to DEH
 */

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import java_cup.runtime.Symbol;
import IC.AST.ASTNode;
import IC.AST.PrettyPrinter;
import IC.AST.Program;
import IC.Parser.Lexer;
import IC.Parser.LibraryParser;
import IC.Parser.Parser;
import LIR.LirTranslation;
import LIR.TranslationVisitor;
import Traversal.SemanticChecker;
import Traversal.SymbolTableCreator;


public class Compiler
{
	private static ASTNode handleFile(String fileName, boolean isLibrary, ASTNode library) throws Exception
	{
		ASTNode root = null;

		File file = new File(fileName);
        FileReader txtFile = new FileReader(fileName);
        Lexer scanner = new Lexer(txtFile);
        
        if (isLibrary)
        {
	        LibraryParser tokefmisne = new LibraryParser(scanner);
	        Symbol parseSymbol = tokefmisne.parse();
	        root = (Program) parseSymbol.value;
        }
        else
        {
	        Parser tokefmisne = new Parser(scanner);
	        Symbol parseSymbol = tokefmisne.parse();
	        root = (Program) parseSymbol.value;
        }
        
        System.out.println("Parsed " + file.getName() + " successfully!");
        
        SymbolTableCreator symbolTableCreator = new SymbolTableCreator(file.getName(), library);
        symbolTableCreator.setLibraryStatus(isLibrary);
        root.accept(symbolTableCreator);

        SemanticChecker semanticChecker = new SemanticChecker();
        root.accept(semanticChecker);
        
        return root;
	}
	
	private static void handleOptions(String fileName, String option, ASTNode node) throws IOException
	{
		if (option.equals("-print-ast"))
		{
			PrettyPrinter printer = new PrettyPrinter("");
			System.out.println(node.accept(printer));
		}
		if (option.equals("-dump-symtab"))
		{
			System.out.println();
			System.out.println(node.getSymbolTable());
			System.out.println();
			System.out.println(TypeTable.Table.toString(fileName));
		}
		if (option.equals("-print-lir"))
		{
	        TranslationVisitor translator = new TranslationVisitor();
	        LirTranslation tr = (LirTranslation)node.accept(translator);
	        
			FileWriter lirFile = new FileWriter("file.lir");
			lirFile.write(tr.getTranslation());
			lirFile.close();
			
			System.out.println("Generated LIR: file.lir");
		}
	}
	
    public static void main(String[] args) throws Exception
    {
        if (args.length == 0) 
        {
            System.out.println("Usage: IC.Compiler <file.ic> [ -L</path/to/libic.sig> ]");
            return;
        }

        try 
        {
        	ASTNode root = null;
        	int startIndex = 1; 

        	if (args.length > 1 &&
        		args[1].startsWith("-L"))
        	{
        		startIndex++;
        		
        		String fileName = args[1].replace("-L", "");
        		
        		ASTNode libraryRoot = handleFile(fileName, true, null);
        		root = handleFile(args[0], false, libraryRoot);
        	}
        	else
        	{
        		root = handleFile(args[0], false, null);
        	}

        	File file = new File(args[0]);
        	
        	for (int i = startIndex; i < args.length; i++)
        		handleOptions(file.getName(), args[i], root);
        }
        catch (ArrayIndexOutOfBoundsException e) 
        {
            System.out.print(e.toString());
        }
    }
}